﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ConditionJudge.Question;

namespace ConditionJudge.Answer
{
    class Libby : IConditionJudge
    {
        public string Judgement(string expression, int x)
        {
            string clearExp = expression.Replace(" ", "");
            StringBuilder Exp01 = new StringBuilder();

            for (int i = 0; i < clearExp.Length; )
            {
                if (clearExp[i] != 'X')
                {
                    Exp01.Append(clearExp[i]);
                    i++;
                }
                else
                {
                    bool HasEqual = (clearExp[i + 2] == '=');
                    Exp01.Append(HasEqual ? ArithmeticRlt(clearExp.Substring(i, 4), x)
                        : ArithmeticRlt(clearExp.Substring(i, 3), x));
                    i += HasEqual ? 4 : 3;
                }
            }

            string ExpNoData ;
            ExpNoData = Exp01.Replace("0", "").Replace("1", "").ToString();
            bool ValidConsistentOr, ValidConsistentAnd;
            while (ExpNoData.Length > 2)
            {
                if ((ExpNoData.ToString().IndexOf("||&&") != -1) || (ExpNoData.ToString().IndexOf("&&||") != -1))
                {
                    return "FF";
                }

                ValidConsistentAnd = ValidConsistentOperator(ExpNoData.ToString(), '&');
                ValidConsistentOr = ValidConsistentOperator(ExpNoData.ToString(), '|');
                if (!ValidConsistentAnd || !ValidConsistentOr)
                {
                    return "FF";
                }

                ExpNoData = RemoveConsistentOperator(ExpNoData.ToString(), "||");
                ExpNoData = RemoveConsistentOperator(ExpNoData.ToString(), "&&");
                ExpNoData = ExpNoData.Replace("(||)", "").Replace("(&&)", "");
            }
            if (ExpNoData == "||" || ExpNoData == "&&")
            {
                return "T";
            }
            return "FF";
        }

        public int ArithmeticRlt(string ArithmeticExp, int x)
        {
            bool result;
            if (ArithmeticExp.Length == 4)
            {
                int compareData = Int32.Parse(ArithmeticExp[3].ToString());
                switch (ArithmeticExp[1])
                {
                    case '>':
                        result = x >= compareData;
                        break;
                    case '<':
                        result = x <= compareData;
                        break;
                    default:
                        result = x != compareData;
                        break;
                }
            }
            else
            {
                int compareData = Int32.Parse(ArithmeticExp[2].ToString());
                switch (ArithmeticExp[1])
                {
                    case '>':
                        result = x > compareData;
                        break;
                    case '<':
                        result = x < compareData;
                        break;
                    default:
                        result = x == compareData;
                        break;
                }
            }
            if (result == true)
                return 1;
            else return 0;
        }

        public bool ValidConsistentOperator(string Expr, char Operator)
        {
            int i = 0;
            while (i < Expr.Length)
            {
                if (Expr[i] == Operator)
                {
                    int j = i+1;
                    while (j < Expr.Length)
                    {
                        if (Expr[j] == Operator)
                        {
                            j++;
                            continue;
                        }
                    }
                    j--;

                    if ((j - i+1) % 2 != 0)
                        return false;
                    i = j + 1;
                    continue;
                }
                i++;
            }
            return true;
        }

        public string RemoveConsistentOperator(string Expr, string Operator)
        {
            StringBuilder CopyExpr = new StringBuilder(Expr);
            int i = Expr.IndexOf(Operator);
            while (i < Expr.Length)
            {
                if ((Expr[i] == Operator[0])&&
                    ((i+2)<Expr.Length?(Expr[i+2]==Operator[0]):false))
                {
                    int j = i+1;
                    while(j<Expr.Length)
                    {
                        if (Expr[j] == Operator[0])
                            j++;
                        else
                            break;
                    }
                    //  A||B||(   A||B||D                    
                    if (i == 0)
                    {
                        if (j != Expr.Length - 1) // A||B||(
                        {                            
                            if ((j - i + 1) >= 4)
                            {
                                CopyExpr.Remove(i, j - i - 1);
                            }
                        }
                        else // A||B||D
                        {
                            CopyExpr.Remove(i, j - i - 1);
                        }
                    }
                    else // )||A||B||( 
                         // )||A||B) , )||A||B , (A||B||(, (A||B||C)
                    {
                        if ((Expr[i - 1] == ')') && (j + 1 < Expr.Length) && (Expr[j + 1] == '('))
                        {
                            CopyExpr.Remove(i, j - i - 3);
                        }
                        else
                        {
                            CopyExpr.Remove(i, j - i - 1);
                        }
                    }
                }
                if (Expr[i] == Operator[0])
                {
                    i += 2;
                    continue;
                }
                i++;
            }
            return CopyExpr.ToString();
        }

    }
}
